#include "ds1302.h"

//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
u8 READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
u8 WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

//---DS1302时钟初始化2023年12月28日星期四15点20分47秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
u8 DS1302_TIME[7] = {0x47, 0x20, 0x15, 0x28, 0x12, 0x04, 0x23};


/**********************************
函数名：ds1302_write_byte
功  能：DS1302写单字节
参  数：addr：地址/命令  dat：数据
返回值：无
***********************************/
void ds1302_write_byte(u8 addr,u8 dat)
{
	u8 i=0;
	
	DS1302_RST=0;
	_nop_();	
	DS1302_CLK=0;//CLK低电平
	_nop_();
	DS1302_RST=1;//RST由低到高变化
	_nop_();

	for(i=0;i<8;i++)//循环8次，每次写1位，先写低位再写高位
	{
		DS1302_IO=addr&0x01;
		addr>>=1;
		DS1302_CLK=1;
		_nop_();
		DS1302_CLK=0;//CLK由低到高产生一个上升沿，从而写入数据
		_nop_();		
	}
	for(i=0;i<8;i++)//循环8次，每次写1位，先写低位再写高位
	{
		DS1302_IO=dat&0x01;
		dat>>=1;
		DS1302_CLK=1;
		_nop_();
		DS1302_CLK=0;
		_nop_();		
	}
	DS1302_RST=0;//RST拉低
	_nop_();	
}

/**********************************
函数名：ds1302_read_byte
功  能：DS1302读单字节
参  数：addr：地址/命令
返回值：读取的数据
***********************************/
u8 ds1302_read_byte(u8 addr)
{
	u8 i=0;
	u8 temp=0;
	u8 value=0;

	DS1302_RST=0;
	_nop_();	
	DS1302_CLK=0;//CLK低电平
	_nop_();
	DS1302_RST=1;//RST由低到高变化
	_nop_();
	
	for(i=0;i<8;i++)//循环8次，每次写1位，先写低位再写高位
	{
		DS1302_IO=addr&0x01;
		addr>>=1;	
		DS1302_CLK=1;
		_nop_();
		DS1302_CLK=0;//CLK由低到高产生一个上升沿，从而写入数据
		_nop_();		
	}
	for(i=0;i<8;i++)//循环8次，每次读1位，先读低位再读高位
	{
		temp=DS1302_IO;
		value=(temp<<7)|(value>>1);//先将value右移1位，然后temp左移7位，最后或运算
		DS1302_CLK=1;
		_nop_();
		DS1302_CLK=0;
		_nop_();		
	}
	//	DS1302_RST=0;//RST拉低，当DS1302与DS18B20同时使用时，不能使用这条语句
	_nop_();	
	DS1302_CLK=1;//对于实物中，P3.4口没有外接上拉电阻的，此处代码需要添加，使数据口有一个上升沿脉冲。
	_nop_();
	DS1302_IO = 0;
	_nop_();
	DS1302_IO = 1;
	_nop_();	
	return value;		
}


/**********************************
函数名：ds1302_init
功  能：DS1302初始化时间
参  数：无
返回值：无
***********************************/
void ds1302_init(void)
{
	u8 i=0;
	ds1302_write_byte(0x8E,0X00);
	for(i=0;i<7;i++)
	{
		ds1302_write_byte(WRITE_RTC_ADDR[i],DS1302_TIME[i]);	
	}
	ds1302_write_byte(0x8E,0X80);	
}

/**********************************
函数名：ds1302_read_time
功  能：DS1302读取时间
参  数：无
返回值：无
***********************************/
void ds1302_read_time(void)
{
	u8 i=0;
	for(i=0;i<7;i++)
	{
		DS1302_TIME[i]=ds1302_read_byte(READ_RTC_ADDR[i]);	
	}	
}